#!/usr/bin/env bash
############################################
# 使用此脚本来获取当前 linux 服务器的相关信息 #
############################################

# 获取脚本当前路径
baseDir="$(cd `dirname $0`; pwd)"
# 定义配置文件路径
configFile="${baseDir}/config"
# 定义日志的路径
csvDir="${baseDir}/csv_save"

# 引用配置文件内的变量
source ${configFile}

# 日志目录不存在则创建
[ -d ${csvDir} ] || mkdir -p ${csvDir}

# 获取当前机器的 ip 和主机名
hostName="$(echo $(hostname -I | awk '{print $1}')_$(cat /etc/hostname))"
# 定义文件的名称
## 文件名称的格式：ip_主机名-日期T时间
fileName="${hostName}-$(date +%FT%H-%M-%S)"
## 定义 csv 文件
csvFile="${fileName}.csv"

# 创建 csv 文件，输入标题
echo "${hostName} check list" |tee ${csvDir}/${csvFile}
echo "name,value,status" >> ${csvDir}/${csvFile}

# 获取 linux 相关信息
function check_linux_msg () {
  ## 获取 linux 发行版
  linuxNname="$(awk -F '=' '/PRETTY_NAME/ {print $NF}' /etc/os-release | sed 's|"||g')"
  ## 获取 linux 内核版本
  kernelVersion="$(uname -r)"

  # 将 linux 发行版和内核版本信息写入 csv 文件，以逗号分隔
  echo "Check Linux,Linux Distribution,${linuxNname}" >> ${csvDir}/${csvFile}
  echo "Check Linux,Kernel Version,${kernelVersion}" >> ${csvDir}/${csvFile}
}

# 获取 CPU 相关信息
function check_cpu_msg () {
  ## 获取 CPU 型号
  cpuName="$(awk -F ': ' '/^model name/ {print $NF}' /proc/cpuinfo | uniq)"
  ## 获取 CPU 架构
  machineArch="$(uname -p)"
  ## 获取 CPU 线程数
  cpuProc="$(grep -c "^processor" /proc/cpuinfo)"
  ## 获取 CPU 指令集数组
  flagsArray=($(printf "%q\n" ${cpuFlags}))

  # 将 CPU 型号信息写入 csv 文件，以逗号分隔
  echo "Check CPU,CPU Name,${cpuName}" >> ${csvDir}/${csvFile}
  # 将 CPU 架构信息写入 csv 文件，以逗号分隔
  echo "Check CPU,CPU Arch,${machineArch}" >> ${csvDir}/${csvFile}
  # 将 CPU 线程数信息写入 csv 文件，以逗号分隔
  echo "Check CPU,CPU Processor,${cpuProc}C" >> ${csvDir}/${csvFile}
  # 将 CPU 指令集信息写入 csv 文件，以逗号分隔
  for (( a=0;a<${#flagsArray[@]};a++ ))
  do
    grep -q "${flagsArray[a]}" /proc/cpuinfo
    if [ "$?" -eq 0 ];then
      echo "Check CPU,CPU Flags: ${flagsArray[a]},exist" >> ${csvDir}/${csvFile}
    else
      echo "Check CPU,CPU Flags: ${flagsArray[a]},disexist" >> ${csvDir}/${csvFile}
    fi
  done
}

# 获取内存相关信息
  function check_mem_msg () {
  ## 获取内存总量
  memTotal="$(awk '/MemTotal:/ {printf "%.2f GB\n", $2/1024/1024}' /proc/meminfo)"

  # 将内存总量信息写入 csv 文件，以逗号分隔
  echo "Check Memory,Memory Total,${memTotal}" >> ${csvDir}/${csvFile}
}

# 获取磁盘相关信息
function check_disk_msg () {
  ## 定义 df 命令的格式
  dfCmd='df -Th -x devtmpfs -x tmpfs -x debugfs -x aufs -x overlay -x fuse.glusterfs'
  diskArray=($(printf "%q\n" ${diskList}))

  for (( i=0; i<${#diskArray[@]}; i++ ))
  do
    diskInfo=$(${dfCmd} | egrep "${diskArray[i]}$")
    diskTotal="$(awk '{print $3}' <<< ${diskInfo})"
    
    echo "Check Disk,Disk partition: ${diskArray[i]},Disk Total: ${diskTotal}" >> ${csvDir}/${csvFile}
  done
}

# 获取 selinx firewalld 的状态
function check_system_msg () {
  # 获取 selinux 状态
  seStatus="$(getenforce)"
  # 获取 firewalld 状态
  ## 判断 firewalld 是否运行中
  fdStatus="$(systemctl is-active firewalld)"
  ## 判断 firewalld 是否开机自启
  fdEnabled="$(systemctl is-enabled firewalld)"

  # 将 selinux 状态信息写入 csv 文件，以逗号分隔
  echo "Check Selinux,Selinux Status,${seStatus}" >> ${csvDir}/${csvFile}
  # 将 firewalld 是否运行的信息写入 csv 文件，以逗号分隔
  echo "Check Firewalld,Firewalld Status,${fdStatus}" >> ${csvDir}/${csvFile}
  # 将 firewalld 是否自启的信息写入 csv 文件，以逗号分隔
  echo "Check Firewalld,Firewalld Enabled,${fdEnabled}" >> ${csvDir}/${csvFile}
}

# 获取 JDK 信息
function check_jdk_msg () {
  ## 获取 java 版本
  javaVersion="$(java -version 2> /dev/null | head -n 1)"

  # 将 JDK 信息写入 csv 文件，以逗号分隔
  if [ "${javaVersion}"x != ""x ];then
    echo "Check JDK,Java Version,${javaVersion}" >> ${csvDir}/${csvFile}
  else
    echo "Check JDK,Java Version,Not found JDK" >> ${csvDir}/${csvFile}
  fi
}

# 获取 MySQL 版本
function check_mysql_msg () {
  ## 判断是否开启了 mysqlCheck
  if [ "${mysqlCheck}"x == "true"x ];then
    mysql --help 2>&1
    # 通过状态码判断是否有 mysql 客户端
    ## 有客户端则判断 mysql 的版本
    ## 无客户端则返回 The client does not exist
    if [ $? -eq 0 ];then
      mysqlVersion=$(mysql -u${mysqlUser} -p${mysqlUser} -h${mysqlPass} -P${mysqlPort} -e "select version();" | grep -v 'password on the command' | sed 's/\^M//g')
      echo "Check MySQL,MySQL Version,${mysqlVersion}" >> ${csvDir}/${csvFile}
    else
      echo "Check MySQL,MySQL Client,disexist" >> ${csvDir}/${csvFile}
    fi
  fi
}

# 判断端口检测工具
function check_port_cmd () {
  checkPortCmd=''

  # 判断 ss 命令是否存在
  whereis ss 2>&1 /dev/null
  # 如果命令存在，定义 checkPortCmd 变量
  if [ "$?" -eq 0 ];then
    checkPortCmd="ss"
  fi

  # 如果 checkPortCmd 变量空值，判断 netstat 命令是否存在
  if [ "${checkPortCmd}"x == ""x ];then
    whereis netstat 2>&1 /dev/null
    if [ "$?" -eq 0 ];then
      checkPortCmd="netstat"
    else
      # 如果 netstat 命令不存在，定义 checkPortCmd 为 none
      checkPortCmd="none"
    fi
  fi
}

# 获取端口占用情况
function check_port_msg () {
  check_port_cmd

  # 如果 checkPortCmd 的值是 none 就不进行后续的操作了
  if [ "${checkPortCmd}"x != "none"x ];then
    ## 定义数组
    serverArray=($(printf "%q\n" ${portLists}))

    for (( p=0;p<${#serverArray[@]};p++ ))
    do
      # 定义服务的名称
      serverName="$(awk -F ':' '{print $1}' <<< ${serverArray[p]})"
      # 定义服务的端口
      serverPort="$(awk -F ':' '{print $2}' <<< ${serverArray[p]})"
      # 判断服务是否有多个端口
      portLine="$(awk -F ',' '{print NF}' <<< ${serverPort})"

      # 如果有多个端口，重新定义 serverPort 变量
      if [ "${portLine}" -gt 1 ];then
        # 通过端口数量进行循环遍历
        for (( i=1;i<=${portLine};i++ ))
        do
          # 通过 awk 来循环定义 serverPort 变量
          serverPortList=$(awk -F ',' "{print \$${i}}" <<< ${serverPort})
          ${checkPortCmd} | grep -q "${serverPortList%%\\*}"
          # 状态码为 0 表示端口存在
          if [ "$?" -eq 0 ];then
            echo "Check Port,${serverName}:${serverPortList%%\\*},exist" >> ${csvDir}/${csvFile}
          else
            echo "Check Port,${serverName}:${serverPortList%%\\*},disexist" >> ${csvDir}/${csvFile}
          fi
        done
        # 如果没有多个端口，直接判断
      else
        ${checkPortCmd} | grep -q "${serverPort}"
        # 状态码为 0 表示端口存在
        if [ "$?" -eq 0 ];then
          echo "Check Port,${serverName}:${serverPort},exist" >> ${csvDir}/${csvFile}
        else
          echo "Check Port,${serverName}:${serverPort},disexist" >> ${csvDir}/${csvFile}
        fi
      fi
    done
  fi
}

# 获取 ntp 服务器状态
function check_ntp_msg () {
  ## 判断是否开启了 ntpCheck
  if [ "${ntpCheck}"x == "true"x ];then
    ntpdate --help 2>&1
    # 通过状态码判断是否有 ntp 客户端
    ## 有客户端则判断 ntpdate 通不通
    ## 无客户端则返回 Check Ntp Server,ntpdate cmd,disexist
    if [ $? -eq 0 ];then
      ntpArray=($(printf "%q\n" ${ntpLists}))
      for (( i=0;i<${#ntpArray[@]};i++ ))
      do
        ntpdate -q ${ntpArray[i]} &> /dev/null
        if [ $? -eq 0 ];then
          echo "Check Ntp Server,ntpserver ip: ${ntpArray[i]},success" >> ${csvDir}/${csvFile}
        else
          echo "Check Ntp Server,ntpserver ip: ${ntpArray[i]},fail" >> ${csvDir}/${csvFile}
        fi
      done
    else
      echo "Check Ntp Server,ntpdate cmd,disexist" >> ${csvDir}/${csvFile}
    fi
  fi
}

# 获取用户信息
function check_user_msg () {
  userArray=($(printf "%q\n" ${userLists}))

  for (( u=0;u<${#userArray[@]};u++ ))
  do
    egrep -q "^${userArray[u]}:" /etc/passwd &> /dev/null
    if [ $? -eq 0 ];then
      echo "Check User,User Name: ${userArray[u]},exist" >> ${csvDir}/${csvFile}
    else
      echo "Check User,User Name: ${userArray[u]},disexist" >> ${csvDir}/${csvFile}
    fi
  done
}

check_linux_msg
check_cpu_msg
check_mem_msg
check_disk_msg
check_system_msg
check_jdk_msg
check_mysql_msg
check_port_msg
check_ntp_msg
check_user_msg